package org.qydjk.common.util.es;

import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.qydjk.common.util.StringUtil;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * ElasticSearch相关的工具类
 */
public class ESearchUtil {
    /**
     * 构造 XContentBuilder
     * @param obj
     * @return
     * @throws IOException
     * @throws IllegalAccessException
     * @throws IntrospectionException
     * @throws InvocationTargetException
     */
    public static XContentBuilder buildXContentBuilder(Object obj) throws IOException, IllegalAccessException, IntrospectionException, InvocationTargetException {
        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder = buildXContentBuilder(obj,builder,null);
        return builder;
    }

    /**
     * 构造 XContentBuilder
     * @param obj
     * @param builder
     * @param name
     * @return
     * @throws IOException
     * @throws IntrospectionException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static  XContentBuilder buildXContentBuilder(Object obj,XContentBuilder builder,String name) throws IOException, IntrospectionException, InvocationTargetException, IllegalAccessException {
        if(builder == null){
            builder = XContentFactory.jsonBuilder();
        }
        if(StringUtil.isEmptyOrNull(name)){
            builder.startObject();
        }else{
            builder.startObject(name);
        }
        List<Field> fieldList = new ArrayList<Field>();
        Class tempClass = obj.getClass();
        while (tempClass != null) {// 当父类为null的时候说明到达了最上层的父类(Object类).
            fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            tempClass = tempClass.getSuperclass();// 得到父类,然后赋给自己
        }
        for (Field field : fieldList) {
            if(field.isAnnotationPresent(ESearchColumn.class)) {
                ESearchColumn eSearchTypeColumn =  field.getAnnotation(ESearchColumn.class);
                ESearchColumnType type = eSearchTypeColumn.type();
                PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), obj.getClass());
                Object value =descriptor.getReadMethod().invoke(obj);
                switch (type){
                    case BASIC:
                        builder.field(field.getName(),value);
                        break;
                    case OBJECT:
                        buildXContentBuilder(value,builder,field.getName());
                        break;
                    case LOCATION:
                        buildXContentBuilder(value,builder,field.getName());
                        break;
                    case LIST_STRING:
                        builder.array(field.getName(),((List<String>)value).toArray());
                        break;
                    case ARRAY_STRING:
                        builder.array(field.getName(),value);
                        break;
                }
            }
        }
        builder.endObject();
        return builder;
    }
}
